/**
 * 
 * @Project le cOeur - Data Virtualization
 * @Date 08.12.2012
 * @Author Aebi Pascal, Kocher Marc
 * @School BFH-TI Biel, Bachelor Thesis
 *
 */

package main.implementation.lecoeur;

import java.io.IOException;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;

import main.api.HTTPClient;
import main.api.exception.ResponseException;
import main.api.http.Response;
import main.api.http.StatusCode;
import main.api.http.StatusLine;
import main.api.setting.Config;

public class LeCoeurAPI extends HTTPClient {

	private String destination;
	
	/**
	 * This class represents the "le cOeur" client API.
	 * It provides a simple way to get the desired information from the "le cOeur" web service.
	 */
	public LeCoeurAPI() {
		if(Integer.parseInt(Config.SECURE_CONNECTION) == 1){
			this.destination = "https://" + Config.RESOURCE_SERVER + ":" + Config.PORT;
		}
		else{
			this.destination = "http://" + Config.RESOURCE_SERVER + ":" + Config.PORT;
		}
	}
	
	
	/* #################### resources #################### */
	
	/**
	 * Sends a HTTP GET request to get a list of all available resource types.
	 * 
	 * @return The string representation of the requested resource.
	 * @throws KeyManagementException If the init operation fails.
	 * @throws UnknownHostException If the host is not known.
	 * @throws NoSuchAlgorithmException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws URISyntaxException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws IOException If an I/O error occurs.
	 * @throws ResponseException If the status code of the response is not 200.
	 */
	public String getResources() throws KeyManagementException, UnknownHostException, NoSuchAlgorithmException, URISyntaxException, IOException, ResponseException {
		Response response = super.get(this.destination + "/resources");
		return this.getResponseMessage(response);
	}

	
	/* #################### indices #################### */
	
	/**
	 * Sends a HTTP GET request to get a list of all indices.
	 * 
	 * @return The string representation of the requested resource.
	 * @throws KeyManagementException If the init operation fails.
	 * @throws UnknownHostException If the host is not known.
	 * @throws NoSuchAlgorithmException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws URISyntaxException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws IOException If an I/O error occurs.
	 * @throws ResponseException If the status code of the response is not 200.
	 */
	public String getIndices() throws KeyManagementException, UnknownHostException, NoSuchAlgorithmException, URISyntaxException, IOException, ResponseException{
		Response response = super.get(this.destination + "/resources/indices");
		return this.getResponseMessage(response);
	}
	
	/**
	 * Sends a HTTP GET request to get a list of information of the specified index.
	 * 
	 * @return The string representation of the requested resource.
	 * @throws KeyManagementException If the init operation fails.
	 * @throws UnknownHostException If the host is not known.
	 * @throws NoSuchAlgorithmException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws URISyntaxException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws IOException If an I/O error occurs.
	 * @throws ResponseException If the status code of the response is not 200.
	 */
	public String getIndex(int index) throws KeyManagementException, UnknownHostException, NoSuchAlgorithmException, URISyntaxException, IOException, ResponseException{
		Response response = super.get(this.destination + "/resources/indices/index" + index);
		return this.getResponseMessage(response);
	}
	
	/**
	 * Sends a HTTP GET request to get the address of the specified index.
	 * 
	 * @return The string representation of the requested resource.
	 * @throws KeyManagementException If the init operation fails.
	 * @throws UnknownHostException If the host is not known.
	 * @throws NoSuchAlgorithmException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws URISyntaxException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws IOException If an I/O error occurs.
	 * @throws ResponseException If the status code of the response is not 200.
	 */
	public String getIndexAddress(int index) throws KeyManagementException, UnknownHostException, NoSuchAlgorithmException, URISyntaxException, IOException, ResponseException{
		Response response = super.get(this.destination + "/resources/indices/index" + index + "/address");
		return this.getResponseMessage(response);
	}
	
	/**
	 * Sends a HTTP GET request to get the consumption of the specified index.
	 * 
	 * @return The string representation of the requested resource.
	 * @throws KeyManagementException If the init operation fails.
	 * @throws UnknownHostException If the host is not known.
	 * @throws NoSuchAlgorithmException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws URISyntaxException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws IOException If an I/O error occurs.
	 * @throws ResponseException If the status code of the response is not 200.
	 */
	public String getIndexConsumption(int index) throws KeyManagementException, UnknownHostException, NoSuchAlgorithmException, URISyntaxException, IOException, ResponseException{
		Response response = super.get(this.destination + "/resources/indices/index" + index + "/consumption");
		return this.getResponseMessage(response);
	}
	
	
	/* #################### energy points #################### */
	
	/**
	 * Sends a HTTP GET request to get a list of all energy points.
	 * 
	 * @return The string representation of the requested resource.
	 * @throws KeyManagementException If the init operation fails.
	 * @throws UnknownHostException If the host is not known.
	 * @throws NoSuchAlgorithmException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws URISyntaxException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws IOException If an I/O error occurs.
	 * @throws ResponseException If the status code of the response is not 200.
	 */
	public String getEnergyPoints() throws KeyManagementException, UnknownHostException, NoSuchAlgorithmException, URISyntaxException, IOException, ResponseException{
		Response response = super.get(this.destination + "/resources/energypoints");
		return this.getResponseMessage(response);
	}
	
	/**
	 * Sends a HTTP GET request to get a list of all information of the specified energy point.
	 * 
	 * @return The string representation of the requested resource.
	 * @throws KeyManagementException If the init operation fails.
	 * @throws UnknownHostException If the host is not known.
	 * @throws NoSuchAlgorithmException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws URISyntaxException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws IOException If an I/O error occurs.
	 * @throws ResponseException If the status code of the response is not 200.
	 */
	public String getEnergyPoint(int energypoint) throws KeyManagementException, UnknownHostException, NoSuchAlgorithmException, URISyntaxException, IOException, ResponseException{
		Response response = super.get(this.destination + "/resources/energypoints/energypoint" + energypoint);
		return this.getResponseMessage(response);
	}
	
	/**
	 * Sends a HTTP GET request to get the address of the specified energy point.
	 * 
	 * @return The string representation of the requested resource.
	 * @throws KeyManagementException If the init operation fails.
	 * @throws UnknownHostException If the host is not known.
	 * @throws NoSuchAlgorithmException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws URISyntaxException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws IOException If an I/O error occurs.
	 * @throws ResponseException If the status code of the response is not 200.
	 */
	public String getEnergyPointAddress(int energypoint) throws KeyManagementException, UnknownHostException, NoSuchAlgorithmException, URISyntaxException, IOException, ResponseException{
		Response response = super.get(this.destination + "/resources/energypoints/energypoint" + energypoint + "/address");
		return this.getResponseMessage(response);
	}
	
	/**
	 * Sends a HTTP GET request to get the type of the specified energy point.
	 * 
	 * @return The string representation of the requested resource.
	 * @throws KeyManagementException If the init operation fails.
	 * @throws UnknownHostException If the host is not known.
	 * @throws NoSuchAlgorithmException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws URISyntaxException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws IOException If an I/O error occurs.
	 * @throws ResponseException If the status code of the response is not 200.
	 */
	public String getEnergyPointType(int energypoint) throws KeyManagementException, UnknownHostException, NoSuchAlgorithmException, URISyntaxException, IOException, ResponseException{
		Response response = super.get(this.destination + "/resources/energypoints/energypoint" + energypoint + "/type");
		return this.getResponseMessage(response);
	}
	
	/**
	 * Sends a HTTP GET request to get the production of the specified energy point.
	 * 
	 * @return The string representation of the requested resource.
	 * @throws KeyManagementException If the init operation fails.
	 * @throws UnknownHostException If the host is not known.
	 * @throws NoSuchAlgorithmException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws URISyntaxException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws IOException If an I/O error occurs.
	 * @throws ResponseException If the status code of the response is not 200.
	 */
	public String getEnergyPointProduction(int energypoint) throws KeyManagementException, UnknownHostException, NoSuchAlgorithmException, URISyntaxException, IOException, ResponseException{
		Response response = super.get(this.destination + "/resources/energypoints/energypoint" + energypoint + "/production");
		return this.getResponseMessage(response);
	}
	
	
	/* #################### battery #################### */
	
	/**
	 * Sends a HTTP GET request to get a list of all information of the battery.
	 * 
	 * @return The string representation of the requested resource.
	 * @throws KeyManagementException If the init operation fails.
	 * @throws UnknownHostException If the host is not known.
	 * @throws NoSuchAlgorithmException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws URISyntaxException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws IOException If an I/O error occurs.
	 * @throws ResponseException If the status code of the response is not 200.
	 */
	public String getBattery() throws KeyManagementException, UnknownHostException, NoSuchAlgorithmException, URISyntaxException, IOException, ResponseException{
		Response response = super.get(this.destination + "/resources/battery");
		return this.getResponseMessage(response);
	}
	
	/**
	 * Sends a HTTP GET request to get the address of the battery.
	 * 
	 * @return The string representation of the requested resource.
	 * @throws KeyManagementException If the init operation fails.
	 * @throws UnknownHostException If the host is not known.
	 * @throws NoSuchAlgorithmException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws URISyntaxException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws IOException If an I/O error occurs.
	 * @throws ResponseException If the status code of the response is not 200.
	 */
	public String getBatteryAddress() throws KeyManagementException, UnknownHostException, NoSuchAlgorithmException, URISyntaxException, IOException, ResponseException{
		Response response = super.get(this.destination + "/resources/battery/address");
		return this.getResponseMessage(response);
	}
	
	/**
	 * Sends a HTTP GET request to get the charge status of the battery.
	 * 
	 * @return The string representation of the requested resource.
	 * @throws KeyManagementException If the init operation fails.
	 * @throws UnknownHostException If the host is not known.
	 * @throws NoSuchAlgorithmException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws URISyntaxException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws IOException If an I/O error occurs.
	 * @throws ResponseException If the status code of the response is not 200.
	 */
	public String getBatteryCharge() throws KeyManagementException, UnknownHostException, NoSuchAlgorithmException, URISyntaxException, IOException, ResponseException{
		Response response = super.get(this.destination + "/resources/battery/charge");
		return this.getResponseMessage(response);
	}
	
	/**
	 * Sends a HTTP GET request to get the usage status of the battery.
	 * 
	 * @return The string representation of the requested resource.
	 * @throws KeyManagementException If the init operation fails.
	 * @throws UnknownHostException If the host is not known.
	 * @throws NoSuchAlgorithmException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws URISyntaxException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws IOException If an I/O error occurs.
	 * @throws ResponseException If the status code of the response is not 200.
	 */
	public String getBatteryUsage() throws KeyManagementException, UnknownHostException, NoSuchAlgorithmException, URISyntaxException, IOException, ResponseException{
		Response response = super.get(this.destination + "/resources/battery/usage");
		return this.getResponseMessage(response);
	}
	
	/**
	 * Returns the message string if the response code of the HTTP response is 200.
	 * 
	 * @param response The HTTP response.
	 * @return The message string.
	 * @throws ResponseException If the response code of the HTTP response is not 200.
	 */
	private String getResponseMessage(Response response) throws ResponseException {
		StatusLine statusLine = (StatusLine) response.getStartLine();
		if(statusLine.getStatusCode() == StatusCode.OK){
			return response.getMessageBody().getMessage();
		}
		else{
			throw new ResponseException("GET request unsuccessful: " + statusLine.getStatusCode().getValue() + " " + statusLine.getReasonPhrase().getValue());
		}
	}

}
